package com.itjcloud.iot.gateway.filter.global;


import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.util.Objects;
import java.util.Optional;

import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
import static org.springframework.cloud.gateway.support.ipresolver.XForwardedRemoteAddressResolver.X_FORWARDED_FOR;

@Slf4j
@Configuration
@ConditionalOnProperty(value = "log.request.enabled", havingValue = "true", matchIfMissing = true)
public class RequestLogFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String ip = getIp(request);
        URI uri = request.getURI();
        URI attribute = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
        String routeId = this.getGatewayRoute(exchange).map(Route::getId).orElse("");
        log.info("ip [调用发起者ip:{}---> 网关转发服务ip:{}], 接口path:[{}} , 转发到的服务: [{}]",
                ip,
                Optional.ofNullable(attribute).map(URI::getAuthority).orElse(""),
                uri.getPath(),
                routeId);
        return chain.filter(exchange);
    }


    /**
     * 获取路由
     *
     * @param exchange 执行器
     * @return 信息
     */
    private Optional<Route> getGatewayRoute(ServerWebExchange exchange) {
        return Optional.ofNullable(exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR));
    }


    private String getIp(ServerHttpRequest request) {
        String ip = request.getHeaders().getFirst(X_FORWARDED_FOR);
        if (ip == null) {
            return Objects.requireNonNull(request.getRemoteAddress()).getHostName();
        }
        return ip;
    }

    /**
     * 顺序必须是<-1，否则标准的NettyWriteResponseFilter将在您的过滤器得到一个被调用的机会之前发送响应
     * 也就是说如果不小于 -1 ，将不会执行获取后端响应的逻辑
     *
     * @return 循序
     */
    @Override
    public int getOrder() {
        return 10151;
    }


}